package br.com.intelsys.iflow.driver.struts;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import br.com.intelsys.iflow.IFlowException;
import br.com.intelsys.iflow.IFlowInstance;
import br.com.intelsys.iflow.IFlowTransition;

public class IFlowInstanceStrutsDriver implements IFlowInstanceStruts {
	private IFlowInstance iFlowInstance;
	private String processName;

	private static final Log log = LogFactory.getLog(IFlowInstanceStrutsDriver.class);

	IFlowInstanceStrutsDriver(String processName, IFlowInstance iFlowInstance) {
		this.processName = processName;
		this.iFlowInstance = iFlowInstance;
	}
	
	String getProcessName() {
		return(processName);
	}
		
	/**
	 * Verifica a partir de um IFlowStrutsAction se existe alguma pendencia que evite a propagacao de um <i>signal</i>
	 * @param action Acao do struts
	 * @return Resultado sobre a checagem
	 */

	/*
	private SignalResult checkTransition(String transitionName) {
		SignalResult sr = null;
		CfgTransition cfgTransition = cfgIFlowStruts.getCfgTransition(transitionName);
		if (cfgTransition != null) {
			boolean executeHandle, didHandle = false;
			List <String> pendingList = action.getPendingList();
			List <CfgHandle> handleList = cfgTransition.getHandleList();
			for (CfgHandle cfgHandle : handleList) {
				List <String> fromList = cfgHandle.getFromList();
				executeHandle = true;
				if (fromList != null) {
					for (String from : fromList) {
						if (from != null) {
							if (!from.equals(this.getStateName())) {
								executeHandle = false;
							}
						}
					}
				}
				if (executeHandle) {
					didHandle = true;
					List <CfgHandleAction> cfgHandleAction = cfgHandle.getHandleActionList();
					if (pendingList != null && !pendingList.isEmpty()) {
						for (String pending : pendingList) {
							log.debug("Procurando actions para "+pending);
							for (CfgHandleAction act : cfgHandleAction) {
								log.debug("Action encontrada: "+act.getName());
								if (act instanceof CfgHandleActionPending) {
									log.debug("Action eh instancia de CfgHandleActionPending");
									if (act.getName() != null && act.getName().equals(pending)) {
										if (sr == null) {
											log.debug("Criado um SignalResult com pendencia.");
											sr = new SignalResult(action, SignalResult.RESULT_PENDING);
										}
										log.debug("Action adicionada: "+act.getName());
										sr.addCfgHandleAction(act);
									}
								}
							}
						}
					} else {
						for (CfgHandleAction act : cfgHandleAction) {
							log.debug("Action encontrada: "+act.getName());
							if (act instanceof CfgHandleActionSuccess) {
								log.debug("Action eh instancia de CfgHandleActionPending");
								log.debug("Criado um SignalResult com sucesso.");
								sr = new SignalResult(SignalResult.RESULT_SUCCESS);
								log.debug("Action adicionada: "+act.getName());
								sr.addCfgHandleAction(act);
								break;
							}
						}
					}
				}
				if (sr != null) {
					break;
				}
			}
		}
		if (sr == null) {
			log.debug("Nenhuma action encontrada. Criando um SignalResult de sucesso sem action.");
			sr = new SignalResult(action, SignalResult.RESULT_SUCCESS);
		}
		return(sr);
	}

	private SignalResult checkTransition(IFlowStrutsAction action, String transitionName) {
		List <String> pendingList = action.getPendingList();
		SignalResult sr = null;
		boolean executeHandle, didHandle = false;
		CfgTransition cfgTransition = this.cfgIFlowStruts.getCfgTransition(transitionName);
		if (cfgTransition != null) {
			if (pendingList != null && !pendingList.isEmpty()) {
				log.debug("Existem pendencias. Checar os handles");
			} else {
				log.debug("Sem pendencia. Procurando a acao de sucesso.");
			}
			List <CfgHandle> handleList = cfgTransition.getHandleList();
			for (CfgHandle cfgHandle : handleList) {
				List <String> fromList = cfgHandle.getFromList();
				executeHandle = true;
				if (fromList != null) {
					for (String from : fromList) {
						if (from != null) {
							if (!from.equals(this.getStateName())) {
								executeHandle = false;
							}
						}
					}
				}
				if (executeHandle) {
					didHandle = true;
					List <CfgHandleAction> cfgHandleAction = cfgHandle.getHandleActionList();
					if (pendingList != null && !pendingList.isEmpty()) {
						for (String pending : pendingList) {
							log.debug("Procurando actions para "+pending);
							for (CfgHandleAction act : cfgHandleAction) {
								log.debug("Action encontrada: "+act.getName());
								if (act instanceof CfgHandleActionPending) {
									log.debug("Action eh instancia de CfgHandleActionPending");
									if (act.getName() != null && act.getName().equals(pending)) {
										if (sr == null) {
											log.debug("Criado um SignalResult com pendencia.");
											sr = new SignalResult(action, SignalResult.RESULT_PENDING);
										}
										log.debug("Action adicionada: "+act.getName());
										sr.addCfgHandleAction(act);
									}
								}
							}
						}
					} else {
						for (CfgHandleAction act : cfgHandleAction) {
							log.debug("Action encontrada: "+act.getName());
							if (act instanceof CfgHandleActionSuccess) {
								log.debug("Action eh instancia de CfgHandleActionPending");
								log.debug("Criado um SignalResult com sucesso.");
								sr = new SignalResult(action, SignalResult.RESULT_SUCCESS);
								log.debug("Action adicionada: "+act.getName());
								sr.addCfgHandleAction(act);
								break;
							}
						}
					}
				}
				if (sr != null) {
					break;
				}
			}
			if (!didHandle) {
				log.debug("Nenhum handle encontrado para o config da transicao: "+cfgTransition.getNameList());
			}
		} else {
			log.debug("Nenhuma configuracao de transicao encontrada para: "+transitionName);
		}
		if (sr == null) {
			log.debug("Nenhuma action encontrada. Criando um SignalResult de sucesso sem action.");
			sr = new SignalResult(action, SignalResult.RESULT_SUCCESS);
		}
		return(sr);
	}
*/
	public SignalResult signal(String transitionName) {
		return(new SignalResult(this, transitionName));
	}

	public SignalResult signal(IFlowTransition transition) {
		return(signal(transition.getName()));
	}
	
	void startSignal(String transitionName) throws IFlowException {
		this.iFlowInstance.signal(transitionName);
	}

	public long getInstanceId() {
		return(this.iFlowInstance.getInstanceId());
	}

	public String getStateName() {
		return(this.iFlowInstance.getStateName());
	}

	public IFlowTransitionStruts getTransition(String name) {
		return(new IFlowTransitionStrutsDriver(this, this.iFlowInstance.getTransition(name)));
	}

	public List<IFlowTransitionStruts> getTransitionList() {
		List <IFlowTransition> ifTrList = this.iFlowInstance.getTransitionList();
		List<IFlowTransitionStruts> l = new ArrayList <IFlowTransitionStruts> ();
		for (IFlowTransition ifTr : ifTrList) {
			l.add(new IFlowTransitionStrutsDriver(this, ifTr));
		}
		return(l);
	}

	public Object getVariable(String name) {
		return(this.iFlowInstance.getVariable(name));
	}

	public Map<String, Object> getVariables() {
		return(this.iFlowInstance.getVariables());
	}

	public void setVariable(String name, Object value) {
		this.iFlowInstance.setVariable(name, value);
	}

	public void save() {
		this.iFlowInstance.save();
	}

}
